package com.example.userdepartment.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * 日志切面
 */
@Aspect
@Component
public class LogAspect {
    
    private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);
    
    /**
     * 定义切点 - 所有controller包下的方法
     */
    @Pointcut("execution(* com.example.userdepartment.controller.*.*(..))")
    public void controllerLog() {}
    
    /**
     * 前置通知：记录请求信息
     */
    @Before("controllerLog()")
    public void doBefore(JoinPoint joinPoint) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            HttpServletRequest request = attributes.getRequest();
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            
            logger.info("========== Request Info ==========");
            logger.info("URI: {}", request.getRequestURI());
            logger.info("Method: {}", request.getMethod());
            logger.info("Class Method: {}.{}", joinPoint.getSignature().getDeclaringTypeName(), method.getName());
            logger.info("IP: {}", request.getRemoteAddr());
            logger.info("Args: {}", Arrays.toString(joinPoint.getArgs()));
            logger.info("================================");
        }
    }
    
    /**
     * 后置通知：记录响应信息
     */
    @AfterReturning(returning = "result", pointcut = "controllerLog()")
    public void doAfterReturning(Object result) {
        logger.info("========== Response Info ==========");
        logger.info("Response: {}", result);
        logger.info("================================");
    }
} 